﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Ooganizer.Closer;
using Ooganizer.Platform.Win32;
using System.Runtime.InteropServices;

namespace Ooganizer.Closer
{
    public class WindowsCloser : ICloser, ICloseable
    {
        public bool CanClose(string processName)
        {
            // This closer will try to close any process the "windows way"
            // Some custom closers may be required for apps that misbehave
            return true;
        }

        public bool CloseApp(IntPtr hWnd, string location)
        {
            int pid = 0;
            Win32Functions.GetWindowThreadProcessId(hWnd, ref pid);

            IntPtr processHandle = Win32Functions.OpenProcess((int)DesiredAccess.SYNCHRONIZE, false, pid);

            int lParam = 0;
            int wParam = 0;
            GCHandle hlParam = GCHandle.Alloc(lParam);
            GCHandle hwParam = GCHandle.Alloc(wParam);

            bool bAllowExit = (Win32Functions.SendMessage(hWnd,
                                                          (int)WindowMessage.WM_QUERYENDSESSION,
                                                          (IntPtr)hwParam,
                                                          (IntPtr)hlParam) != 0);

            if (bAllowExit)
            {
                lParam = 0; // (int)EndSessionBehavior.ENDSESSION_CLOSEAPP
                wParam = 1;

                if (Win32Functions.SendMessage(hWnd,
                                              (int)WindowMessage.WM_ENDSESSION,
                                              (IntPtr)hwParam,
                                              (IntPtr)hlParam) != 0)
                {
                    lParam = 0;
                    wParam = 0;

                    // Apparently the app does not respond to WM_QUERYENDSESSION ... so just send WM_CLOSE
                    Win32Functions.PostMessage(hWnd,
                                               (int)WindowMessage.WM_CLOSE,
                                               (IntPtr)hwParam,
                                               (IntPtr)hlParam);
                }
            }
            else
            {
                // App has indicated that it cannot be shutdown without losing data ... go ahead and stop unloading
                //MessageBox.Show("Could not unload workspace: One of the apps indicated it could not shut down properly.",
                //                "OOganizer",
                //                MessageBoxButton.OK,
                //                MessageBoxImage.Stop);

                return false;
            }

            Win32Functions.WaitForSingleObject(processHandle, (uint)WaitTime.INFINITE);

            return true;
        }
    }
}
